package com.yunao.web.controller;

import com.yunao.commons.Exception.YunaoException;
import com.yunao.commons.enums.ResultEnum;
import com.yunao.commons.serachcore.core.bean.*;
import com.yunao.commons.serachcore.core.help.GroupField;
import com.yunao.commons.constant.CookieConstant;
import com.yunao.commons.constant.RedisConstant;
import com.yunao.commons.serachcore.core.help.SearchFiled;
import com.yunao.commons.utils.CookieUtil;
import com.yunao.commons.utils.JsonUtil;
import com.yunao.commons.utils.ResultVOUtil;
import com.yunao.commons.vo.ResultVO;
import com.yunao.entity.Subject;
import com.yunao.entity.User;
import com.yunao.service.SubjectService;
import com.yunao.service.UserService;
import com.yunao.service.report.Convert;
import com.yunao.web.annotation.UserLoginToken;
import com.yunao.web.convert.QueryForm2Map;
import com.yunao.web.convert.SubjectForm2SubjectConverter;
import com.yunao.web.form.QueryForm;
import com.yunao.web.form.SubjectForm;
import com.yunao.service.report.ExcelWriter;
import com.yunao.web.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.util.*;

@RestController
@RequestMapping("/subject/subject/")
@Slf4j
public class SubjectController {
    @Autowired
    private SubjectService subjectService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserService userService;

    private static List<String> locallist = null;




    @PostMapping("/save")
    @Transactional
    @UserLoginToken
    public ResultVO save(@Valid SubjectForm subjectForm,
                         BindingResult bindingResult,
                         HttpServletRequest request){
        if (bindingResult.hasErrors()){
            log.error("【创建专题】参数不正确");
            throw new YunaoException(ResultEnum.PARAM_ERROR.getCode(),
                    bindingResult.getFieldError().getDefaultMessage());
        }
        Subject subject = SubjectForm2SubjectConverter.convert(subjectForm);
        subject.setIshome(0);
        User user = TokenUtil.getTokenUser(userService);
        subject.setUserId(user.getUserId());
        subject.setOrganId(user.getOrganId());
        subjectService.save(subject);
        user.setSubjectNum(user.getSubjectNum()+1);
        userService.save(user);
        return ResultVOUtil.success();
    }



    @UserLoginToken
    @RequestMapping("/indexTrend")
    public ResultVO indexSubject(HttpServletRequest request){
        String userId = TokenUtil.getTokenUserId();
        Map result = new HashMap();
        List<Subject> subjects = subjectService.findByUserIdAndIshome(Convert.getInt(userId),1);
        Map map = new HashMap();
        map.put("group",GroupField.DAY.toString());
        map.put("days","15");
        for (Subject subject : subjects){
            map.put("keywords",subject.getWord());
            Groups groups = subjectService.group(map);
            result.put(subject.getSubjectName(),groups);
        }
        return ResultVOUtil.success(result);
    }


    @RequestMapping("/indexInfo")
    public ResultVO indexSubjectInfo(){
        String userId = TokenUtil.getTokenUserId();
        List list = new ArrayList();
        List<Subject> subjects = subjectService.findByUserIdAndIshome(Convert.getInt(userId),1);
        Map map = new HashMap();
        map.put("days","3");
        map.put("message_type","正文");
        map.put("limit","15");
        for (Subject subject : subjects){
            Map hmap = new HashMap();
            Articles articles = subjectService.searchSubject(subject.getSubjectId(),map);
            hmap.put("subjectid",subject.getSubjectId());
            hmap.put("subjectname",subject.getSubjectName());
            hmap.put("subjectdata",articles);
            list.add(hmap);
        }
        return ResultVOUtil.success(list);
    }



    @RequestMapping("/list")
    public ResultVO getList(@RequestParam("subjectType")Integer subjectType,HttpServletRequest request){
        String userId = TokenUtil.getTokenUserId();
        List<Subject> subjects = subjectService.findFirstlevelBySubjectType( Convert.getInt(userId),0,subjectType);
        List<Subject> result = new ArrayList<>();
        for (Subject subject : subjects) {
            subject.setChildren(subjectService.findByParentIdAndSubjectType(subject.getSubjectId(),subjectType));
            result.add(subject);
        }
        return ResultVOUtil.success(result);
    }


    @UserLoginToken
    @RequestMapping("/listNoLevel")
    public ResultVO listNoLevel(){
        String userId = TokenUtil.getTokenUserId();
        List<Subject> subjects = subjectService.findListByUser( Convert.getInt(userId));
        return ResultVOUtil.success(subjects);
    }

    @UserLoginToken
    @RequestMapping("/firstlevellist")
    public ResultVO firstlevellist(Integer parentid, HttpServletRequest request){
        return ResultVOUtil.success(stringRedisTemplate.opsForValue().get("TRADE"));
    }

    @UserLoginToken
    @RequestMapping("/getSubject")
    public Integer getSubject(String subjectName){
        Subject subject = subjectService.findByName(subjectName);
        return subject.getSubjectId();
    }

    @UserLoginToken
    @RequestMapping("/delete")
    @Transactional
    public ResultVO delelteSubject(@RequestParam(value = "subjectId") Integer subjectId){
        subjectService.delete(subjectId);
        User user = TokenUtil.getTokenUser(userService);
        user.setSubjectNum(user.getSubjectNum()-1);
        userService.save(user);
        return ResultVOUtil.success();
    }


    @PostMapping("/querySubject")
    public ResultVO querySubject(QueryForm queryForm){
        Subject subject = null;
        if(queryForm.getId()!=null){
            subject = subjectService.findOne(queryForm.getId());
        }
        Map map = QueryForm2Map.searchConvert(queryForm,subject);
        return ResultVOUtil.success(subjectService.searchSubject(queryForm.getId(),map));
    }

    @RequestMapping("/exportbyids")
    public ResultVO exportbyids(String ids, QueryForm queryForm, String num, String medias,
                                HttpServletResponse response) throws FileNotFoundException {
//        int[] idarr = Convert.str2int(ids.split(","));
        Map map = new HashMap();
        if (!StringUtils.isEmpty(ids)){
            map.put("id",ids);
        }else {
            map = QueryForm2Map.searchConvert(queryForm,null);
            if (StringUtils.isNotEmpty(medias)){
                map.put("media_type",medias);
            }
            map.put("limit",num);
        }
        Articles articles = subjectService.query(map);
        // 导出文件夹存放导出文件的临时文件
        String path = System.getProperty("user.dir").replace("bin", "webapps") + "\\export\\";
        File file = new File(path);
        if (!file.exists())
            file.mkdirs();
        // 导出文件 文件名称
        file = new File(path + System.currentTimeMillis() + ".xls");
        // 保存为临时文件
        OutputStream out = new FileOutputStream(file);
        ExcelWriter writer = new ExcelWriter(articles.getData(), out);
        writer.write();
        String fileName = "Esou_Export_Execl.xls";
        response.setHeader("Content-disposition", "attachment; filename=" + fileName);
        BufferedOutputStream bufo = null;
        try {
            bufo = new BufferedOutputStream(response.getOutputStream());
            InputStream in = new FileInputStream(file);
            int read = 0;
            byte[] tempbytes = new byte[1024];
            while ((read = in.read(tempbytes)) != -1) {
                bufo.write(tempbytes, 0, read);
                bufo.flush();
            }
        } catch (Exception e) {

        } finally {
            try {
                if (bufo != null)
                    bufo.close();
            } catch (Exception e) {

            }
        }
        return ResultVOUtil.success();
    }

    @UserLoginToken
    @GetMapping("/metiaByDays")
    public ResultVO groupByMD(@RequestParam("subjectId") Integer subjectId){
        Map result = new HashMap();
//        Map map = new HashMap();
        Map<String,String> map = addSubjectQuery(subjectService.findOne(subjectId));
        map.put("group",SearchFiled.MEDIA_TYPE.toString());
        map.put("days","1");
        Groups groups1 = subjectService.group(map);
        map.put("days","3");
        Groups groups3 = subjectService.group(map);
        map.put("days","7");
        Groups groups7 = subjectService.group(map);
        result.put("day1",groups1);
        result.put("day3",groups3);
        result.put("day7",groups7);
        return ResultVOUtil.success(result);
    }

    @UserLoginToken
    @GetMapping("/totalTrend")
    public ResultVO totalTrend(@RequestParam("subjectId") Integer subjectId,
                               @RequestParam(name = "days",required = false,defaultValue = "3")Integer queryDays){
//        int daynum = queryDays==0?3:queryDays;
        Map<String,String> map = addSubjectQuery(subjectService.findOne(subjectId));
        map.put("group",SearchFiled.GROUPBYDAY.toString());
        map.put("group2",SearchFiled.MEDIA_TYPE.toString());
        map.put("days",queryDays+"");
        return ResultVOUtil.success(subjectService.cube(map));
    }
    @UserLoginToken
    @GetMapping("/picture")
    public ResultVO picture(@RequestParam("subjectName") String name){
        String nameBase64Url = stringRedisTemplate.opsForValue().get(name);
        return ResultVOUtil.success(nameBase64Url);
    }

    @UserLoginToken
    @RequestMapping("/groupByField")
    public ResultVO groupByField(@RequestParam("subjectId") Integer subjectId,
                                 @RequestParam(name = "days",required = false,defaultValue = "3")Integer queryDays){
//        locallist = getinit();
        Map result = new HashMap();
        Map<String,String> map = addSubjectQuery(subjectService.findOne(subjectId));
        map.put("days",queryDays+"");
        Wordclouds wordclouds =subjectService.searchWordclouds(map);
        Wordrelations wordrelations = subjectService.wordrelation(map);
        map.put("group",SearchFiled.MEDIA_TYPE.toString());
        Groups groups1 = subjectService.group(map);
        map.put("group",SearchFiled.EMOTION.toString());
        Groups groups2 = subjectService.group(map);
        map.put("group",SearchFiled.DOMAIN_LEVEL.toString());
        Groups groups3 = subjectService.group(map);
        map.put("group",SearchFiled.DOMAIN.toString());
        map.put("limit","10");
        Groups groups4 = subjectService.group(map);
        map.put("group",SearchFiled.LOCATION.toString());
        map.put("limit","1500");
        Groups groups5 = selectPro(subjectService.group(map));
        map.put("media_type","微博");
        map.put("group",SearchFiled.AUTHOR.toString());
        map.put("limit","15");
        Groups groups6 = selectPro(subjectService.group(map));
        map.put("media_type","微信");
        map.put("group",SearchFiled.AUTHOR.toString());
        map.put("limit","15");
        Groups groups7 = selectPro(subjectService.group(map));
        result.put("media",groups1);
        result.put("emotion",groups2);
        result.put("domainLevel",groups3);
        result.put("domain",groups4);
        result.put("location",groups5);
        result.put("wordcloud",wordclouds);
        result.put("wordrelation",wordrelations);
        result.put("weiboRanks",groups6);
        result.put("weichartRanks",groups7);
        return ResultVOUtil.success(result);
    }

    private Groups selectPro(Groups groups){
        List<Group> list = new ArrayList<>(36);
        int total=0;
        for (Group group : groups.getData()) {
//            if (locallist.contains(group.getKey())){
            if (StringUtils.isEmpty(group.getKey())){
                continue;
            }
            if (!group.getKey().contains(":")){
//                System.out.println(group.getKey());
                list.add(group);
                total += group.getValue();
            }
        }
        Groups result = new Groups(total);
        for (Group group : list){
            result.addData(group);
        }
        return result;
    }
    @UserLoginToken
    @RequestMapping("/cluster")
    public ResultVO cluster(@RequestParam(value = "subjectId") Integer subjectId){
        return ResultVOUtil.success(subjectService.cluster(subjectId));
    }
    @UserLoginToken
    @RequestMapping("/findByUserId")
    public ResultVO findByUserId(@RequestParam(value = "userId") Integer userId){
        return ResultVOUtil.success(subjectService.findListByUser(userId));
    }




    private Map addSubjectQuery(Subject subject){
        Map map= new HashMap();
        if (StringUtils.isEmpty(subject.getRemoveWord()))
            map.put("keywords",subject.getWord());
        else
            map.put("keywords",subject.getWord()+"-"+subject.getRemoveWord());
        if (!StringUtils.isEmpty(subject.getSubjectLocaltion())){
            map.put("location",subject.getSubjectLocaltion());
        }
        return map;
    }

    private List<String> getinit() {
        String[] locals = new String[]{"广西省", "甘肃省", "广东省", "河北省",
                "四川省", "山东省", "河南省", "北京市", "黑龙江省", "江苏省", "浙江省", "湖北省",
                "湖南省", "西藏自治区", "辽宁省", "江西省", "青海省", "上海市", "陕西省", "福建省",
                "云南省", "安徽省", "天津市", "吉林省", "山西省", "贵州省", "海南省", "重庆市",
                "新疆维吾尔自治区", "内蒙古自治区", "香港特别行政区", "台湾省", "宁夏回族自治区", "澳门特别行政区"};
        if (locallist == null) {
            locallist = Arrays.asList(locals);
        }
        return locallist;
    }



}
